package com.javasea.netty.har.client.netty;

import com.javasea.netty.har.client.config.ClientConfig;
import com.javasea.netty.har.common.utils.BeanTools;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.util.ResourceLeakDetector;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @ClassName: PrinterClinet
 * @Date: 2018/8/1 12:36
 * @Description:
 */
@Component
@Slf4j
public class PrinterClient {

    public static ChannelFuture cf;
    private static Bootstrap b;

    public void start(){
        ClientConfig clientProps = BeanTools.getBean(ClientConfig.class);
        log.info("获取到的clientCode：[{}], host：[{}], port：[{}]",clientProps.getNioClientCode(),clientProps.getHost(),clientProps.getPort());
        this.connect(clientProps.getNioClientCode(),clientProps.getHost(),clientProps.getPort());
    }

    public void connect(String nioClientCode, String host, Integer port)  {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            b = new Bootstrap();
            b.group(group)
                .option(ChannelOption.SO_KEEPALIVE,true)
                .channel(NioSocketChannel.class)
                .handler(new ClientChannelInitializer(nioClientCode,host,port));
            // 将警告级别设置成Advaced即可查到更详细的泄漏信息，之后再度查看日志：
            ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
            doConnect();
            // 启动客户端时，为成功连接服务端，由监听器定时进行重连
            cf.addListener(new ConnectionListener());
        }catch (Exception e){
            log.error("连接时报错!, tenantId:{}, host:{}, port:{}", nioClientCode, host, port);
        }
    }

    /**
     * 抽取出该方法 (断线重连时使用)
     * @throws InterruptedException
     */
    public static ChannelFuture doConnect() {
        ClientConfig clientProps = BeanTools.getBean(ClientConfig.class);
        try {
            log.info("服务地址为：[{}]，端口为：[{}], 连接代码为：[{}] 正在连接中...",clientProps.getHost(),clientProps.getPort(),clientProps.getNioClientCode());
            cf = b.connect(clientProps.getHost(),clientProps.getPort());
            if(cf.isSuccess()){
                log.info("重连成功！");
            }
            return cf;
        } catch (Exception e) {
            log.error("执行doConnect方法发生异常",e);
        }
        return null;
    }

}
